import { _decorator, CCInteger, Component, Prefab, Node, instantiate, director } from "cc"
import NetworkManager from "../Global/NetworkManager"
import { ApiMsgEnum, IApiPlayerListRes, IApiRoomListRes } from "../Common"
import { PlayerManager } from "../UI/PlayerManager"
import DataManager from "../Global/DataManager"
import { EventEnum, SceneEnum } from "../Enum"
import { RoomManager } from "../UI/RoomManager"
import EventManager from "../Global/EventManager"
const { ccclass, property } = _decorator

@ccclass("HallManager")
export class HallManager extends Component {
    @property(Node)
    playerContainer: Node

    @property(Prefab)
    playerPrefab: Prefab

    @property(Node)
    roomContainer: Node

    @property(Prefab)
    roomPrefab: Prefab

    onLoad() {
        EventManager.Instance.on(EventEnum.RoomJoin, this.handleJoinRoom, this)
        NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgPlayerList, this.renderPlayer, this)
        NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgRoomList, this.renderRoom, this)
    }

    start() {
        this.playerContainer.destroyAllChildren()
        this.roomContainer.destroyAllChildren()
        this.getPlayers()
        this.getRooms()
    }

    onDestroy() {
        EventManager.Instance.off(EventEnum.RoomJoin, this.handleJoinRoom, this)
        NetworkManager.Instance.unlistenMsg(ApiMsgEnum.MsgPlayerList, this.renderPlayer, this)
        NetworkManager.Instance.unlistenMsg(ApiMsgEnum.MsgRoomList, this.renderRoom, this)
    }

    async getPlayers() {
        const { success, error, res } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiPlayerList,
            {}
        )
        if (!success) {
            console.error("获取玩家列表失败: ", error)
            return
        }
        console.log("res: ", res)

        this.renderPlayer(res)
    }

    renderPlayer({ list }: IApiPlayerListRes) {
        for (const e of this.playerContainer.children) {
            e.active = false
        }

        while (this.playerContainer.children.length < list.length) {
            const node = instantiate(this.playerPrefab)
            node.active = false
            node.setParent(this.playerContainer)
        }

        for (let i = 0; i < list.length; i++) {
            const data = list[i]
            const node = this.playerContainer.children[i]
            node.getComponent(PlayerManager).init(data)
        }
    }

    async getRooms() {
        const { success, error, res } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomList,
            {}
        )
        if (!success) {
            console.error("获取玩家列表失败: ", error)
            return
        }
        console.log("res: ", res)

        this.renderRoom(res)
    }

    renderRoom({ list }: IApiRoomListRes) {
        for (const e of this.roomContainer.children) {
            e.active = false
        }

        while (this.roomContainer.children.length < list.length) {
            const node = instantiate(this.roomPrefab)
            node.active = false
            node.setParent(this.roomContainer)
        }

        for (let i = 0; i < list.length; i++) {
            const data = list[i]
            const node = this.roomContainer.children[i]
            node.getComponent(RoomManager).init(data)
        }
    }

    async handleCreateRoom() {
        const { success, error, res } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomCreate,
            {}
        )
        if (!success) {
            console.error("创建房间失败: ", error)
            return
        }

        console.log("创建房间成功: ", res.room)
        DataManager.Instance.roomInfo = res.room
        director.loadScene(SceneEnum.Room)
    }

    async handleJoinRoom(rid: number) {
        const { success, error, res } = await NetworkManager.Instance.callApi(
            ApiMsgEnum.ApiRoomJoin,
            { rid }
        )
        if (!success) {
            console.error("加入房间失败: ", error)
            return
        }

        console.log("加入房间成功: ", res.room)
        DataManager.Instance.roomInfo = res.room
        director.loadScene(SceneEnum.Room)
    }

}